using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using WbsEditor.Properties;

namespace WbsEditor
{
    public partial class WbsWorkItemSelectionForm : Form
    {
        public WbsWorkItemSelectionForm()
        {
            InitializeComponent();
        }

        private WbsTfsClient _tfsClient;
        public WbsTfsClient TfsClient
        {
            get { return _tfsClient; }
            set { _tfsClient = value; }
        }

        List<WbsItem> _wbsItems = new List<WbsItem>();
        List<WbsItem> WbsItems
        {
            get
            {
                return _wbsItems;
            }
        }

        public int WorkItemId
        {
            get
            {
                int id = 0;
                if (workItemList.SelectedItems.Count > 0)
                {
                    ListViewItem item = workItemList.SelectedItems[0];
                    string workItemString = item.SubItems[1].Text;
                    int.TryParse(workItemString, out id);
                }
                return id;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            workItemList.View = Settings.Default.BrowseForWorkItemView;

            if (!string.IsNullOrEmpty(TfsClient.TeamProject))
                RunQuery();
            InitCombos();

            base.OnLoad(e);
        }

        private void InitCombos()
        {
            string[] projects = TfsClient.GetTeamProjectNames();
            teamProjectCombo.Items.AddRange(projects);
            teamProjectCombo.Text = TfsClient.TeamProject;

            InitIterations();
        }

        private void InitIterations()
        {
            string currentFilter = filterCombo.Text;
            filterCombo.Items.Clear();
            filterCombo.Items.Add("All items");
            filterCombo.Items.Add("Active items");
            filterCombo.Items.Add("Closed items");
            if (!string.IsNullOrEmpty(TfsClient.TeamProject))
            {
                string[] iterations = TfsClient.GetTeamProjectIterations();
                filterCombo.Items.AddRange(iterations);
            }

            if (string.IsNullOrEmpty(currentFilter)
                || !filterCombo.Items.Contains(currentFilter))
            {
                filterCombo.SelectedIndex = 0;
                filterCombo.Text = "All items";
            }
            else
            {
                filterCombo.Text = currentFilter;
            }
        }

        private void RunQuery()
        {
            WbsItems.Clear();
            if (!string.IsNullOrEmpty(TfsClient.TeamProject))
            {
                int filterIndex = filterCombo.SelectedIndex;
                string filterString = "";
                switch (filterIndex)
                {
                    case 0: break;
                    case 1: filterString = "AND [System.State] = 'Active'"; break;
                    case 2: filterString = "AND [System.State] = 'Closed'"; break;
                    default: filterString =
                        string.Format("AND [System.IterationPath] = '{0}'",
                            filterCombo.Text);
                        break;
                }
                string wiq = string.Format("SELECT [System.Id], [System.Title], [System.AssignedTo] FROM WorkItems WHERE [System.TeamProject]='{0}' AND ([System.Title] CONTAINS '(WBS Editor)') {1} ORDER BY [System.Title]",
                    TfsClient.TeamProject,
                    filterString);
                WorkItemCollection wiColl = TfsClient.GetWorkItemsFromQuery(wiq);
                foreach (WorkItem workItem in wiColl)
                {
                    WbsItem item = new WbsItem();
                    item.Title = StripWbsEditorText(workItem.Title);
                    item.AssignedTo = workItem.Fields["Assigned To"].Value.ToString();
                    item.Id = workItem.Id;
                    item.Iteration = workItem.IterationPath;
                    WbsItems.Add(item);
                }
            }
            RebuildItemList();
        }

        private void RebuildItemList()
        {
            workItemList.Items.Clear();
            string searchText = _searchEdit.Text;
            foreach (WbsItem wbsItem in WbsItems)
            {
                if (string.IsNullOrEmpty(searchText)
                    || wbsItem.Contains(searchText))
                {
                    ListViewItem item = new ListViewItem(wbsItem.Title);
                    item.ImageIndex = 0;
                    item.SubItems.Add(new ListViewItem.ListViewSubItem(item, wbsItem.Id.ToString()));
                    item.SubItems.Add(new ListViewItem.ListViewSubItem(item, wbsItem.AssignedTo));
                    workItemList.Items.Add(item);
                }
            }
        }

        private void TryDirectJump()
        {
            if (workItemList.Items.Count == 1)
            {
                workItemList.Items[0].Selected = true;
                DialogResult = DialogResult.OK;
                Dispose();
            }
            else if (workItemList.Items.Count > 1)
            {
                workItemList.Items[0].Selected = true;
                workItemList.Focus();
            }
        }

        private string StripWbsEditorText(string p)
        {
            string tag = "(WBS Editor) ";
            if (p.StartsWith(tag))
            {
                return p.Substring(tag.Length);
            }
            else
            {
                return p;
            }
        }

        private void teamProjectCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            string project = teamProjectCombo.Text;
            if (TfsClient.TeamProject == project)
                return;

            TfsClient.TeamProject = project;
            InitIterations();
            RunQuery();
        }

        private void filterCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            RunQuery();
        }

        private void viewButton_Click(object sender, EventArgs e)
        {
            if (workItemList.View == View.Details)
                workItemList.View = View.LargeIcon;
            else
                workItemList.View = View.Details;

            Settings.Default.BrowseForWorkItemView = workItemList.View;
        }

        private void workItemList_DoubleClick(object sender, EventArgs e)
        {
            if (workItemList.SelectedItems.Count > 0)
            {
                DialogResult = DialogResult.OK;
                Close();
            }
        }

        private void workItemList_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (workItemList.SelectedItems.Count > 0)
                okButton.Enabled = true;
            else
                okButton.Enabled = false;
        }

        private void _searchEdit_TextChanged(object sender, EventArgs e)
        {
            RebuildItemList();
        }

        private void _searchEdit_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                TryDirectJump();
                e.Handled = true;
            }
        }

        private void _searchEdit_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                e.IsInputKey = true;
            }
        }
    }

    class WbsItem
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string AssignedTo { get; set; }
        public string Iteration { get; set; }

        public bool Contains(string text)
        {
            return ((Id.ToString().IndexOf(text, StringComparison.InvariantCultureIgnoreCase) >= 0)
                || (Title.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) >= 0)
                || (AssignedTo.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) >= 0)
                || (Iteration.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) >= 0));
        }
    }
}